﻿var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
var FormItem = new Interface('FormItem', ['save', 'restore']);

var CompositeForm = function (id, method, action) {
    this.formComponents = [];

    this.element = document.createElement('form');
    this.element.id = id;
    this.element.method = method || 'POST';
    this.element.action = action || '#';
};

CompositeForm.prototype.add = function (child) {
    Interface.ensureImplements(child, Composite, FormItem);
    this.formComponents.push(child);
    this.element.appendChild(child.getElement());
};

CompositeForm.prototype.remove = function (child) {
    for (var i = 0, len = this.formComponents.length; i < len; i++) {
        if (this.formComponents[i] = child) {
            this.formComponents.splice(i, 1);
            break;
        }
    }
};

CompositeForm.prototype.getChild = function (i) {
    return this.forComponents[i];
};

CompositeForm.prototype.save = function () {
    for (var i = 0, len = this.formComponents.length; i < len; i++) {
        this.formComponents[i].save();
    }
};

CompositeForm.prototype.restore = function () {
    for (var i = 0, len = this.formComponents.length; i < len; i++) {
        this.formComponents[i].restore();
    }
};

CompositeForm.prototype.getElement = function (i) {
    return this.element;
};

var Field = function (id) {
    this.id = id;
    this.element;
};

Field.prototype.add = function () { };
Field.prototype.remove = function () { };
Field.prototype.getChild = function () { };

Field.prototype.save = function () {
    $.cookie(this.id, this.getValue());
};

Field.prototype.restore = function () {
    $(this.element).find('#'+this.id).val($.cookie(this.id));
};

Field.prototype.getElement = function () {
    return this.element;
};

Field.prototype.getValue = function () {
    throw new Error('Unsupported operation on the class Field.');
};

var InputField = function (id, label) {
    Field.call(this, id);

    this.input = document.createElement('input');
    this.input.id = id;

    this.label = document.createElement('label');
    var labelTextNode = document.createTextNode(label);
    this.label.appendChild(labelTextNode);

    this.element = document.createElement('div');
    this.element.className = 'input-field';
    this.element.appendChild(this.label);
    this.element.appendChild(this.input);
};
extend(InputField, Field);

InputField.prototype.getValue = function () {
    return this.input.value;
};

var TextareaField = function (id, label) {
    Field.call(this.id);

    this.textarea = document.createElement('textarea');
    this.textarea.id = id;

    this.label = document.createElement('label');
    var labelTextNode = document.createTextNode(label);
    this.label.appendChild(labelTextNode);

    this.element = document.createElement('div');
    this.element.className = 'input-field';
    this.element.appendChild(this.label);
    this.element.appendChild(this.textarea);
};
extend(TextareaField, Field);
TextareaField.prototype.getValue = function () {
    return this.textarea.value;
};


var SelectField = function (id, label, data) {
    Field.call(this.id);

    this.select = document.createElement('select');
    this.select.id = id;

    for (var i = 0, len = data.length; i < len; i++) {
        var option = document.createElement('option');
        option.text = data[i].name;
        option.value = i;
        this.select.appendChild(option);
    }

    this.label = document.createElement('label');
    var labelTextNode = document.createTextNode(label);
    this.label.appendChild(labelTextNode);

    this.element = document.createElement('div');
    this.element.className = 'input-field';
    this.element.appendChild(this.label);
    this.element.appendChild(this.select);
};
extend(SelectField, Field);
SelectField.prototype.getValue = function () {
    return this.select.options[this.select.selectedIndex].value;
};



var CompositeFieldset = function (id, legendText) {
    this.components = {};

    this.element = document.createElement('fieldset');
    this.element.id = id;

    if (legendText) {
        this.legend = document.createElement('legend');
        this.legend.appendChild(document.createTextNode(legendText));
        this.element.appendChild(this.legend);
    }
};

CompositeFieldset.prototype.add = function (child) {
    Interface.ensureImplements(child, Composite, FormItem);
    this.components[child.id] = child;
    this.element.appendChild(child.getElement());
};

CompositeFieldset.prototype.remove = function (child) {
    delete this.components[child.id];
};

CompositeFieldset.prototype.getChild = function (id) {
    if (this.components[id] != undefined) {
        return this.components[id];
    } else {
        return null;
    }
};

CompositeFieldset.prototype.save = function () {
    for (var id in this.components) {
        if (!this.components.hasOwnProperty(id)) {
            continue;
        }
        this.components[id].save();
    }
};

CompositeFieldset.prototype.restore = function () {
    for (var id in this.components) {
        if (!this.components.hasOwnProperty(id)) {
            continue;
        }
        this.components[id].restore();
    }
};

CompositeFieldset.prototype.getElement = function () {
    return this.element;
};

